OPcache
OPcache is a PHP extension that improves performance by caching precompiled PHP bytecode in shared memory. Instead of parsing and compiling PHP scripts on every request, PHP can reuse cached bytecode, reducing CPU usage and improving response times for PHP applications.
PHP historically compiled scripts at runtime for each request, which made CPU consumption and latency scale poorly under traffic. Bytecode caching emerged to reduce this overhead, and OPcache became the widely adopted, built-in bytecode cache included with modern PHP distributions.
OPcache is commonly used on:
- Web servers running PHP (Apache with PHP-FPM, Nginx with PHP-FPM, OpenLiteSpeed)
- CMS platforms (WordPress, Drupal, Joomla)
- PHP frameworks and applications (Laravel, Symfony, custom apps)
Maintained by
- Maintained by the PHP project community.
Best When to Use
- Your server runs PHP applications that handle repeated requests (web apps, APIs, CMS).
- CPU usage is high due to PHP script compilation overhead.
- You want a low-risk performance improvement without changing application code.
- You deploy via PHP-FPM or any long-running PHP process model.
Not Suitable When
- You run short-lived PHP CLI workloads where caching provides little benefit.
- You cannot allocate shared memory (highly constrained environments).
- You rely on rapid code changes without controlled reloads (development workflows need different settings).
Compatibility Notes
-
OPcache is typically available by default in modern PHP builds, but may need to be installed or enabled depending on the distribution package.
-
Configuration differs slightly across distros due to file layout (
php.iniandconf.dlocations). -
OPcache behavior differs between:
- PHP-FPM/Apache module (persistent processes benefit most)
- PHP CLI (optional; often disabled or tuned differently)
-
With containers, OPcache works normally, but ensure the shared memory and configuration are sized for the container limits.
Misconfigured OPcache can cause unexpected behavior if application deployment does not trigger PHP-FPM reloads. In production, use a controlled deploy workflow and reload PHP-FPM after code updates.
How OPcache Works
Key points:
- Cached bytecode lives in shared memory inside the PHP process environment.
- Cache is shared across worker processes (depends on SAPIs and configuration).
- Cache invalidation depends on timestamps, revalidation settings, and process reloads.
Installation
Debian/Ubuntu
sudo apt update
sudo apt install php-opcache
RHEL/CentOS Stream/Fedora
sudo dnf install php-opcache
Alpine
sudo apk add php-opcache
Verify OPcache Status (Read-Only)
Check if the extension is loaded
For PHP-FPM or CLI:
php -m | grep -i opcache || true
Show effective configuration
php --ini
php -i | grep -i -E 'opcache|configuration file'
Confirm OPcache is enabled
php -i | grep -i -E '^opcache\.enable|^opcache\.enable_cli'
php -i reflects the CLI configuration. PHP-FPM and web server SAPIs may use different php.ini and conf.d paths. Always confirm the configuration for the specific SAPI you are running (PHP-FPM pool or Apache module).
Configuration Locations
Common paths (varies by distro and PHP version):
| Environment | Common config location examples |
|---|---|
| -- | |
| Debian/Ubuntu (PHP-FPM) | /etc/php/<version>/fpm/conf.d/ |
| Debian/Ubuntu (Apache) | /etc/php/<version>/apache2/conf.d/ |
| Debian/Ubuntu (CLI) | /etc/php/<version>/cli/conf.d/ |
| RHEL/Fedora | /etc/php.d/ |
Use this to find the active paths:
php --ini
Recommended Baseline Settings
Add or adjust OPcache settings in an OPcache ini file (commonly 10-opcache.ini or similar) or in php.ini.
Example baseline (production-oriented):
opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.validate_timestamps=1
opcache.revalidate_freq=2
opcache.save_comments=1
opcache.fast_shutdown=1
Meaning of key settings:
| Setting | Purpose | Notes |
|---|---|---|
| - | ||
opcache.enable | Enable OPcache | Should be 1 for web workloads |
opcache.memory_consumption | Shared memory size (MB) | Increase if cache fills frequently |
opcache.max_accelerated_files | Script cache capacity | Set based on codebase size |
opcache.validate_timestamps | Detect file changes | Keep 1 unless you always reload on deploy |
opcache.revalidate_freq | Recheck frequency (seconds) | Lower for frequent deploys; higher for stability |
opcache.save_comments | Keep doc comments | Usually required for frameworks/annotations |
opcache.enable_cli | Enable for CLI | Often 0 unless needed |
If your deployment process reliably reloads PHP-FPM after code changes, you can set opcache.validate_timestamps=0 for better performance. Only do this when you are certain reloads happen every deploy.
Apply Changes Safely
After configuration changes, reload the correct service:
PHP-FPM
Service name depends on PHP version and distro.
sudo systemctl reload php-fpm 2>/dev/null || true
sudo systemctl reload php8.2-fpm 2>/dev/null || true
sudo systemctl reload php8.1-fpm 2>/dev/null || true
sudo systemctl status php-fpm 2>/dev/null || true
If reload is unsupported, restart:
sudo systemctl restart php8.2-fpm 2>/dev/null || true
sudo systemctl restart php-fpm 2>/dev/null || true
Apache with mod_php
sudo systemctl reload apache2 2>/dev/null || sudo systemctl reload httpd 2>/dev/null
Practical Use Cases
Improve WordPress and CMS performance
Baseline:
- Enable OPcache
- Ensure enough memory (
opcache.memory_consumption) - Keep
opcache.save_comments=1
Verify improvement:
- Watch CPU usage under load
- Confirm fewer compile operations in OPcache stats (if you expose stats internally)
High-traffic PHP API (Laravel/Symfony)
Typical tuning:
- Increase
opcache.max_accelerated_filesfor larger codebases - Ensure
opcache.memory_consumptionis sufficient - Use deploy-triggered reloads to allow safe timestamp validation tuning
Troubleshooting
| Symptom | Likely Cause | Safe Checks | Fix | |
|---|---|---|---|---|
| - | - | |||
| OPcache not loaded | Package not installed or extension disabled | php -m, `php -i | grep opcache` | Install/enable php-opcache, reload PHP-FPM/Apache |
| No effect on performance | Wrong SAPI configured | Compare CLI vs FPM config paths | Configure OPcache for PHP-FPM/Apache, not only CLI | |
| Frequent cache full / restarts | Insufficient memory or file slots | Check OPcache status, logs | Increase memory_consumption and max_accelerated_files | |
| Users see old code after deploy | Timestamp checks disabled or low revalidation | Confirm deploy reload behavior | Reload PHP-FPM on deploy, or enable timestamp validation | |
| Random errors after enable | Missing comments or aggressive optimizations | Review settings | Ensure opcache.save_comments=1, revert aggressive flags |
If you disable timestamp validation and do not reload PHP-FPM on deploy, users may continue running old code indefinitely. Treat deploy-triggered reload as mandatory in that mode.
Security Notes
- Do not expose OPcache status pages publicly. They can reveal file paths, environment details, and application structure.
- Use least-privilege access for any diagnostic endpoints, and restrict by network or authentication.
Quick Reference Cheat Sheet
| Goal | Command / Setting |
|---|---|
| -- | - |
| Check OPcache loaded | php -m | grep -i opcache |
| Show active ini files | php --ini |
| Enable OPcache | opcache.enable=1 |
| Size shared memory | opcache.memory_consumption=128 |
| Keep framework annotations | opcache.save_comments=1 |
| Reload PHP-FPM | sudo systemctl reload php8.x-fpm |
| Reload Apache | sudo systemctl reload apache2 or sudo systemctl reload httpd |